package com.matt.service.impl;

import com.matt.domain.Contract;
import com.matt.domain.statistics.*;
import com.matt.foundation.constant.ContractConstant;
import com.matt.foundation.utils.DateUtil;
import com.matt.repository.ClienteleRepository;
import com.matt.repository.ContractRepository;
import com.matt.repository.statictics.*;
import com.matt.service.AnalysisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import javax.persistence.NonUniqueResultException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.matt.foundation.constant.AnalysisConstant.*;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2018/7/3
 * *******************************
 */
@Service
@Slf4j
public class AnalysisServiceImpl implements AnalysisService{

    @Autowired
    private StatsInitiativeLeadsRepository statsInitiativeLeadsRepository;

    @Autowired
    private StatExpectIncomeRepository statExpectIncomeRepository;

    @Autowired
    private ContractRepository contractRepository;

    @Autowired
    private StatEndClienteleRepository statEndClienteleRepository;

    @Autowired
    private StatRenewalClienteleRepository statRenewalClienteleRepository;

    @Override
    public StatLeads create(String leadsId, Integer category, String channelId, String areaId, String staffId, Date date) {
        StatLeads leads = statsInitiativeLeadsRepository.findByLeadsIdAndType(leadsId, LEADS_CREATED);
        if (Objects.isNull(leads))
            return statsInitiativeLeadsRepository.save(StatLeads.of(leadsId, LEADS_CREATED, category, channelId, areaId, staffId, date));
        return null;
    }

    @Override
    public StatLeads arrival(String leadsId, Integer category, String channelId, String areaId, String staffId, Date date) {
        StatLeads leads = statsInitiativeLeadsRepository.findByLeadsIdAndType(leadsId, LEADS_ARRIVAL);
        if (Objects.isNull(leads))
            return statsInitiativeLeadsRepository.save(StatLeads.of(leadsId, LEADS_ARRIVAL, category, channelId, areaId, staffId, date));
        return null;
    }

    @Override
    public StatLeads deal(String leadsId, Integer category, String channelId, String areaId, String staffId, Date date) {
        StatLeads leads = statsInitiativeLeadsRepository.findByLeadsIdAndType(leadsId, LEADS_DEAL);
        if (Objects.isNull(leads))
            return statsInitiativeLeadsRepository.save(StatLeads.of(leadsId, LEADS_DEAL, category, channelId, areaId, staffId, date));
        return null;
    }

    @Override
    public StatExpectIncome createExpectIncome(String clienteleId, String contractId, BigDecimal amount, Integer type, Integer productType, String areaId, Date date) {
        if(StringUtils.isEmpty(contractId)){
            return null;
        }

        //System.out.println(String.format("createExpectIncome %s,%s,%s", clienteleId,contractId,areaId ));

        if (type == CONTRACT_PRODUCT_NEW){
            return statExpectIncomeRepository.save(StatExpectIncome.of(clienteleId, contractId, amount, type, productType, areaId, date));
        }else if (type == CONTRACT_PRODUCT_RENEWAL){
            List<StatExpectIncome> incomes = statExpectIncomeRepository.findByContractId(contractId);
            StatExpectIncome statExpectIncome = incomes.size()>0 ? incomes.get(0) : null;
            if(incomes.size() > 0){
                log.error("duplicate record for expect income {}", contractId);
            }
            if (Objects.isNull(statExpectIncome))
                return statExpectIncomeRepository.save(StatExpectIncome.of(clienteleId, contractId, amount, type, productType, areaId, date));
        }

        return null;
    }


    //检查是否所有合同结束，如果都结束，设置客户结束状态
    @Override
    public StatEndClientele createEndClient(String clienteleId, Integer type, String areaId, Date date) {
        List<Contract> normalContracts = contractRepository.findByClienteleIdAndStatus(clienteleId, ContractConstant.Status.NORMAL.codeOf());
        Date begin = DateUtil.getCurrentDayBeginAndEnd(DateUtil.parseDateToString(date)).get("beg");
        Date end = DateUtil.getCurrentDayBeginAndEnd(DateUtil.parseDateToString(date)).get("end");
        StatEndClientele statEndClientele=null;
        if (normalContracts.isEmpty()){
            statEndClientele = statEndClienteleRepository.findByClienteleIdAndCreatedBetween(clienteleId, begin, end);
            if (Objects.isNull(statEndClientele)){
                statEndClientele = StatEndClientele.of(clienteleId, type, areaId, date);
                statEndClienteleRepository.save(statEndClientele);
            }

        }
        return statEndClientele;
    }

    @Override
    public StatRenewalClientele createNeedRenewalClientele(String clienteleId, String contractId, Integer type, Boolean isRenewed, String areaId) {
        StatRenewalClientele clientele = null;
        try {
            clientele = statRenewalClienteleRepository.findAnyByClienteleIdAndTypeAndIsRenewed(clienteleId, type, false);
        }catch (RuntimeException e){
            List<StatRenewalClientele> list = statRenewalClienteleRepository.findByClienteleIdAndTypeAndIsRenewed(clienteleId, type, false);
            if (list.size() > 0){
                clientele = list.get(0);
            }

            log.error("create need renewal clientele duplicate record {},{},{}，{}，{}", clienteleId, contractId, type, isRenewed, areaId);
        }
        if (Objects.isNull(clientele))
            statRenewalClienteleRepository.save(StatRenewalClientele.of(clienteleId, contractId, type, isRenewed, areaId));
        return clientele;
    }

    @Override
    public StatRenewalClientele renewalClientele(String clienteleId, Integer type) {
        StatRenewalClientele clientele = null;
        try {
            clientele = statRenewalClienteleRepository.findAnyByClienteleIdAndTypeAndIsRenewed(clienteleId, type, false);
        }catch (RuntimeException e){
            List<StatRenewalClientele> list = statRenewalClienteleRepository.findByClienteleIdAndTypeAndIsRenewed(clienteleId, type, false);
            if (list.size() > 0){
                clientele = list.get(0);
            }

            log.error("renewal clientele duplicate record {},{}", clienteleId, type);
        }

        if (Objects.nonNull(clientele)){
            clientele.setIsRenewed(true);
            clientele.setRenewalDate(new Date());
            return statRenewalClienteleRepository.save(clientele);
        }
        return null;

    }
}
